<template>
  <div>
    <p>pageRouter: #/$set</p>
    <br />
    <p>动态给vue的data添加一个新的属性时会发生什么？怎样解决？</p>
    <br />
    <pre>
    测试数据：
{{ item }}
    </pre>

    <ul>
      <li v-for="(value, key) in item"
          :key="key">{{ key + ':' + value }}</li>
    </ul>
    <br />
    <button @click="addProperty">动态添加新属性</button>
    &nbsp;
    <button @click="addMoreProperty">动态添加更多新属性</button>
    <br /><br />
    &nbsp;
    <button @click="addPropertyForForcecUpdated">
      动态添加新属性（forcecUpdated()）
    </button>
    <br />
    <!--  -->
    <div>
      <button @click="changeItemAfterOneSecond">
        changeItemAfterOneSecond
      </button>
      <button @click="addProperty">更新</button>
    </div>
    <br /><br />
    <HR size="2" />
    <pre>
若想实现数据与视图同步更新，可采取下面三种解决方案：

Vue.set()
Object.assign()
$forcecUpdated() ：迫使 Vue 实例重新渲染。注意它仅仅影响实例本身和插入插槽内容的子组件，而不是所有子组件。</pre>
    <br />
    <a href="https://vue3js.cn/interview/vue/data_object_add_attrs.html#%E4%B8%89%E3%80%81%E8%A7%A3%E5%86%B3%E6%96%B9%E6%A1%88"
       target="_blank"
       rel="noopener noreferrer">解决方案详情</a>
    <hr />
    <br />
    <button @click="changeTest">
      我这个test没有用在模板上更新test看看会不会走一次updated生命周期</button><br /><br />
    <p>
      在data中定义了test属性 然而并没有用在模板上
      改变这个属性是不会触发这个组件的更新的即不会走那些生命周期钩子函数
    </p>
  </div>
</template>

<script>
export default {
  name: 'myTest',
  components: {},
  data() {
    return {
      item: {
        oldProperty: '旧属性'
      },
      test: '我这个test没有用在模板上更新test看看会不会走一次updated生命周期'
    }
  },
  methods: {
    addProperty() {
      // this.item.newProperty = '新属性' //问题:为item数据对象添加新属性(页面不会更新)
      // - 解决办法
      // 1 Vue.set() ;  $set是Vue.set的别名
      this.$set(this.item, 'newProperty', '新属性')
      // 2,Object.assign(): 直接使用Object.assign()添加到对象的新属性不会触发更新应创建一个新的对象，合并原对象和混入对象的属性
      // this.item = Object.assign({}, this.item, { newProperty: '新属性' })

      // 3 $forceUpdate
      // this.$forceUpdate()
      console.log(this.item) // 输出带有newProperty的items
    },
    addMoreProperty() {
      const willAddObj = {}
      for (let i = 0; i < 10; i++) {
        willAddObj['newProperty' + i] =
          '新属性' + Math.round(Math.random() * 10)
      }
      // 不叠加是因为Object.ssign这个方法重复的键用后面的
      this.item = Object.assign({}, this.item, willAddObj)
    },
    addPropertyForForcecUpdated() {
      this.item.testForcecUpdated = '新属性ForcecUpdated'
      console.log('forceUpdate前：', this.item)
      this.$forceUpdate()
      console.log('forceUpdate后：', this.item)
    },
    changeTest() {
      this.test = '我更新了'
    },
    changeItemAfterOneSecond() {
      window.setTimeout(() => {
        this.item = {
          oldProperty: '1231231',
          new: '1231321'
        }
      }, 1000)
    }
  },
  updated() {
    console.log('测试一下test属性')
  },
  activated: {},
  deactivated: {}
}
</script>
<style lang="less" scoped></style>
